from django.utils.decorators import method_decorator

from gis.common.django_ext.decorators import validate_parameters
from gis.common.django_ext.views import BaseView, PaginationResponse
from gis.common.exceptions import BizException
from itpay.core.agency import agency_service
from itpay.core.agency.const import AgencyType
from itpay.core.agency.errors import ERROR_AGREE_AGENCY_NOT_BELONG
from itpay.core.recharge_order import order_service, recharge_comment_service
from itpay.core.recharge_order.const import RechargeSourceType, OrderStatus
from itpay.core.recharge_order.errors import (
    ERROR_CANNOT_CREATE_ORDER,
    ERROR_ORDER_NOT_BELONG,
)
from itpay.server_agency.decorators import require_login
from itpay.server_agency.view.agency.helper import wrapper_name
from . import order_form


class OrderListView(BaseView):
    @method_decorator(require_login())
    @method_decorator(validate_parameters(order_form.ListOrdersSchema))
    def get(self, request, cleaned_data):
        user = request.user
        if AgencyType(user["agency_type"]) == AgencyType.ADMIN_AGENCY:
            cleaned_data["parent_id"] = user["id"]
        elif AgencyType(user["agency_type"]) == AgencyType.NORMAL_AGENCY:
            cleaned_data["agency_id"] = user["id"]
        if cleaned_data.get("status") == OrderStatus.SUCCESS:
            cleaned_data["status"] = [OrderStatus.SUCCESS, OrderStatus.CHASE_FROZEN]
        c, ls = order_service.list_orders(**cleaned_data)
        return PaginationResponse(c, ls)

    @method_decorator(require_login())
    @method_decorator(validate_parameters(order_form.AddOrderSchema))
    def post(self, request, cleaned_data):
        user = request.user
        if AgencyType(user["agency_type"]) != AgencyType.NORMAL_AGENCY:
            raise BizException(ERROR_CANNOT_CREATE_ORDER)
        agency_id = request.user_id
        return order_service.create_order(
            agency_id, **cleaned_data, source=RechargeSourceType.AGENCY_MAN
        )


class OrderDetailView(BaseView):
    @method_decorator(require_login())
    def get(self, request, order_id):
        return order_service.get_order(order_id)


class OrderCommitView(BaseView):
    @method_decorator(require_login(check_vcode=True))
    @method_decorator(validate_parameters(order_form.ChangeOrderStatusSchema))
    def put(self, request, order_id, cleaned_data):
        order = order_service.get_order_by_id(order_id)
        if order["agency_id"] != request.user_id:
            raise BizException(ERROR_ORDER_NOT_BELONG)
        need_review = order_service.need_order_review(order_id)
        remark = cleaned_data["remark"] or "commit by agency"
        return order_service.commit_order(
            order_id, remark=remark, need_review=need_review
        )


class OrderCancelView(BaseView):
    @method_decorator(require_login())
    @method_decorator(validate_parameters(order_form.ChangeOrderStatusSchema))
    def put(self, request, order_id, cleaned_data):
        order = order_service.get_order_by_id(order_id)
        if order["agency_id"] != request.user_id:
            raise BizException(ERROR_ORDER_NOT_BELONG)
        return order_service.cancel_order(order_id, cleaned_data["remark"])


class OrderChaseView(BaseView):
    @method_decorator(require_login(check_vcode=True))
    @method_decorator(validate_parameters(order_form.ChangeOrderStatusSchema))
    def put(self, request, order_id, cleaned_data):
        _check_permission(order_id, request.user_id)
        return order_service.chase_order(order_id, cleaned_data["remark"])


class ReviewRechargeAgreeView(BaseView):
    @method_decorator(require_login(check_vcode=True))
    def put(self, request, order_id):
        _check_permission(order_id, request.user_id)

        order_service.review_success(order_id)
        return dict(id=order_id)


class ReviewRechargeRefuseView(BaseView):
    @method_decorator(require_login(check_vcode=True))
    def put(self, request, order_id):
        _check_permission(order_id, request.user_id)
        order_service.review_fail(order_id)

        return dict(id=order_id)


class RechargeCommentView(BaseView):
    @method_decorator(require_login())
    @method_decorator(validate_parameters(order_form.OrderCommentSchema))
    def get(self, request, cleaned_data):
        parent_name = request.user["user_name"]
        count, comment = recharge_comment_service.list_pay_order_comment(
            **cleaned_data, parent_name=parent_name
        )
        return PaginationResponse(count, [wrapper_name(e) for e in comment])


def _check_permission(order_id, user_id):
    order = order_service.get_order_by_id(order_id)
    if not agency_service.check_agency_parent(order["agency_id"], user_id):
        raise BizException(ERROR_AGREE_AGENCY_NOT_BELONG)
